package org.correct.search;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Map;

import org.correct.config.*;
import org.correct.model.PageItem;
import org.correct.servlet.Initializer;

public class Search extends Thread{
	ArrayList<String> keywords;
	
	static HashMap<String, String> cache = new HashMap<String, String>();
	
	public Search(ArrayList<String> keywords){
		this.keywords = keywords;
	}
	
	public Object[] query(int page){	
		ArrayList<HashMap<Integer, Double>> records = new ArrayList<HashMap<Integer, Double>>();
		for(int i = 0; i < keywords.size(); i++){
			//System.out.println(keywords.get(i));
			records.add(query(keywords.get(i)));
		}
		Object[] ret = new Object[2];
		if(records.isEmpty()){
			return ret;
		}
		TreeMap<Integer, Double> similarity = new TreeMap<Integer, Double>();
		Iterator<Integer> iterator = records.get(0).keySet().iterator();
		while(iterator.hasNext()){
			similarity.put(iterator.next(), 0.0);							
		}
		for(int i = 1; i < records.size(); i++){
			iterator = similarity.keySet().iterator();
			while(iterator.hasNext()){
				int d = iterator.next();
				if(!records.get(i).containsKey(d)){
					iterator.remove();
				}							
			}
		}
		
		iterator = similarity.keySet().iterator();
		double maxSim = 0, maxPR = 0;
		while(iterator.hasNext()){
			int d = iterator.next();
			double sum = 0;
			double length = 0;
			for(int i = 0; i < records.size(); i++){
				double t;
				try{
					t = records.get(i).get(d);
				}catch (NullPointerException e) {
					t = 0;
				}
				sum += t;
				length += t * t;
			}
			double sim = sum ;// Math.sqrt(length);
			if(sim > maxSim){
				maxSim = sim;
			}
			double PR = Initializer.pageInfo.getItem(d).pageRank;
			if(PR > maxPR){
				maxPR = PR;
			}
			similarity.put(d, sim);
		}
		//System.out.println(maxSim + ":" + maxPR);
		iterator = similarity.keySet().iterator();
		while(iterator.hasNext()){
			int d = iterator.next();
			double sort = similarity.get(d) / maxSim + Initializer.pageInfo.getItem(d).pageRank / maxPR;
			similarity.put(d, sort);
			//System.out.println(d + ":" +sort);
		}
		ArrayList<Map.Entry<Integer, Double>> infolds = new ArrayList<Map.Entry<Integer, Double>>(similarity.entrySet());
		Collections.sort(infolds, new Comparator<Map.Entry<Integer, Double>>() {
			public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2){
				return (int)((o2.getValue() - o1.getValue()) * 1000000);
			}
		});
		
		// TODO I modified this piece.
		
		int k = Config.ITEM_NUM_PER_PAGE;
		if(k * page > infolds.size()){
			k = infolds.size() % Config.ITEM_NUM_PER_PAGE;
		}
		PageItem[] result = new PageItem[k];
		for(int i = 0; i < k; i++){
			result[i] = new PageItem(infolds.get(Config.ITEM_NUM_PER_PAGE * (page - 1) + i).getKey(), keywords);

			//System.out.println(infolds.get(i).toString());
		}
		
		/*
		LinkedList<PageItem> result = new LinkedList<PageItem>();
		for(int i = Config.RESULT_PER_PAGE * (page - 1); i < Config.RESULT_PER_PAGE * page && i < infolds.size(); i++) {
			result.add(new PageItem(infolds.get(i).getKey(), keywords));
		}
		*/
		
		
		ret[0] = infolds.size();
		ret[1] = result;
		return ret;
	}
	
	public HashMap<Integer, Double> query(String term){
		int value = term.hashCode() % 1000000;
		//System.out.println(term + "\t" + value);
		HashMap<Integer, Double> result = new HashMap<Integer, Double>();
		if(cache.containsKey(term)){
			String s = cache.get(term);
			String[] strs = s.split(" ");
			for(int i = 1; i < strs.length; i++){
				String[] t = strs[i].split(":");
				result.put(Integer.parseInt(t[0]),Double.parseDouble(t[1]));
			}
			return result;
		}
		int acc = 0;
		while(true){
			File file;
			if(acc == 0){
				file = new File(Initializer.basePath + Config.INDEX_PATH + Math.abs(value) / Config.TERM_PER_FILE);
			}else{
				file = new File(Initializer.basePath + Config.INDEX_PATH + Math.abs(value) / Config.TERM_PER_FILE + "_" + acc);
			}
			if(!file.exists()){
				break;
			}
			try{
				FileInputStream fis = new FileInputStream(file);
				BufferedReader br = new BufferedReader(new InputStreamReader(fis));				
				int k = (value > 0) ? value % Config.TERM_PER_FILE : (value % Config.TERM_PER_FILE + 100);
				for(int i = 0; i < k; i++){
					br.readLine();
				}
				String s = br.readLine();					
				if(s == null || s.equals("")){						
					break;
				}else{
					String[] strs = s.split(" ");
					if(strs[0].equals(term)){
						cache.put(term, s);
						if(cache.size() == 1000){
							ArrayList<String> list = new ArrayList<String>(cache.keySet());
							int pos = (int)Math.floor(Math.random() * 1000);
							System.out.println(list.get(pos));
							cache.remove(list.get(pos));
						}
						for(int i = 1; i < strs.length; i++){
							String[] t = strs[i].split(":");
							result.put(Integer.parseInt(t[0]),Double.parseDouble(t[1]));
						}
					}else{
						acc++;
						br.close();
						fis.close();
						continue;
					}
				}
			}catch(Exception e){
				e.printStackTrace();
				System.out.println("查询" + term + "出错");
			}
			break;
		}
		return result;
	}
	
}
